//
//  CXJSONFormat.swift
//  CXPack
//
//  Created by 陈警卫 on 2023-12-25.
//

import Foundation
import XcodeKit
import SwiftyJSON

class CXJSONFormat {
    
    static func apart(_ invocation: XCSourceEditorCommandInvocation) {
        guard let range = invocation.buffer.selections.firstObject as? XCSourceTextRange else { return }
        var start = range.start.line
        var end = range.end.line
        
        if end > (invocation.buffer.lines.count - 1) {
            end = (invocation.buffer.lines.count - 1)
        }
        if start > end {
            start = end
        }
        var code = ""
        for lineNum in start...end {
            code += invocation.buffer.lines[lineNum] as! String
        }
        let modelString = apartJSON(code: code)
        let line = end + 1
        invocation.buffer.lines.insert(modelString, at: line)
    }
    
    static func apartJSON(code: String) -> String {
        
        let json = JSON(parseJSON: code)
        
        var modelString = ""
        modelString += apartDict(json: json)
        
        return modelString
    }
    
    static func apartDict(json: JSON) -> String {
        let apartPrefix = "\nstruct <#Model#>: Codable {\n"
        let apartSuffix = "\n}"
        var apartString = ""
        var subString = ""
        
        if json.type == .dictionary {
            let dict = json.dictionaryValue
            let keys = dict.keys
            for key in keys {
                if let value = dict[key] {
                    var type = "String"
                    if value.type == .array {
                        type = "[<#Model#>]"
                        let json = value[0]
                        subString += apartDict(json: json)
                    } else if value.type == .dictionary {
                        type = "[<#String#>: <#Model#>]"
                        let json = value
                        subString += apartDict(json: json)
                    } else if value.type == .number {
                        type = "Int"
                    }
                    apartString += "    var \(key): \(type)?\n"
                }
            }
        } else if json.type == .array {
            let json = json[0]
            apartString += apartDict(json: json)
        }
        var modelString = apartPrefix + apartString + apartSuffix
        modelString += subString
        return modelString
    }
}
